<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Pango</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="GUI, PyGTK, Pango, Python, programming, Linux">
<meta nam="description" content="Pango">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div> 

<div class="content">

<a href="/" title="Home">Home</a>&nbsp;
<a href="..">Contents</a>


<h1>Pango</h1>

<p>
In this part of the PyGTK programming tutorial, we will continue exploring the Pango library.
</p>

<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* NewSquare */
google_ad_slot = "0364418177";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script>


<h2>Animated text</h2>

<p>
The following example shows animated text on window.   
</p>

<div class="codehead">animation.py</div> 
<pre class="code">
#!/usr/bin/python

# ZetCode PyGTK tutorial 
#
# This example shows animated text
#
# author: jan bodnar
# website: zetcode.com 
# last edited: February 2009

import gtk
import glib
import pango
import math


class PyApp(gtk.Window): 
    def __init__(self):
        super(PyApp, self).__init__()
        
        self.connect("destroy", gtk.main_quit)
        glib.timeout_add(160, self.on_timer)
        
        self.count = 1
        
        self.set_border_width(10)
        self.set_title("ZetCode")
        
        self.label = gtk.Label("ZetCode")
      
        fontdesc = pango.FontDescription("Serif Bold 30")
        self.label.modify_font(fontdesc)

        vbox = gtk.VBox(False, 0)
        vbox.add(self.label)
        
        self.add(vbox)
        self.set_size_request(300, 250)
        self.set_position(gtk.WIN_POS_CENTER)
        self.show_all()
        
    def on_timer(self):
        attr = pango.AttrList()
        self.count = self.count + 1
                 
        for i in range(7):
            r = pango.AttrRise(int(math.sin(self.count+i)*20)*pango.SCALE, i, i+1)
            attr.insert(r)
                        
        self.label.set_attributes(attr)
        return True
        
         
PyApp()
gtk.main()
</pre>

<p>
In the above code example, we have a text in a label widget.
By continuously changing its pango attributes, the text is being
animated.
</p>

<pre class="explanation">
 self.label = gtk.Label("ZetCode")
      
 fontdesc = pango.FontDescription("Serif Bold 30")
 self.label.modify_font(fontdesc)
</pre>

<p>
We create a label widget and modify its font.
We choose a bit larger text for better visibility.
</p>

<pre class="explanation">
 vbox = gtk.VBox(False, 0)
 vbox.add(self.label)
</pre>

<p>
We put the label into the vertical box. This centers 
the label on the window.
</p>

<p>
The animation is performed inside the <b class="keyword">on_timer()</b>
method.
</p>

<pre class="explanation">
 for i in range(7):
     r = pango.AttrRise(int(math.sin(self.count+i)*20)*pango.SCALE, i, i+1)
     attr.insert(r)
</pre>

<p>
We have seven characters in our text. We periodically change the pango
<b class="keyword">AttrRise</b> attribute for each character. The
rise is based on the trigonometric sine function. The text movement
follows the sine function graphed on the cartesian graph.
</p>

<p>
Also notice the <b class="keyword">pango.SCALE</b> constant. The pango
library has its own units. They differ from what is used by the widgets
to draw graphics or text. We must multiply our numbers by this constant.
</p>


<br>
<img src="/img/gui/pygtk/sine.png" alt="Animated text">
<div class="figure">Figure: Animated text</div>
<br>

<h2>Using markup language</h2>

<p>
We can change the attributes of the text using the
built-in markup language. 
</p>

<div class="codehead">markup.py</div>
<pre class="code"> 
#!/usr/bin/python

# ZetCode PyGTK tutorial 
#
# This example uses markup language
# to change attributes of the text
#
# author: jan bodnar
# website: zetcode.com 
# last edited: February 2009

import gtk
import pango

quote = "&lt;span foreground='blue' size='19000'&gt;The only victory over love is flight&lt;/span&gt;"


class PyApp(gtk.Window): 
    def __init__(self):
        super(PyApp, self).__init__()
        
        self.set_title("Markup")
        self.set_border_width(5)
        self.connect("destroy", gtk.main_quit)
        
        label = gtk.Label()
        label.set_markup(quote)

        vbox = gtk.VBox(False, 0)
        vbox.add(label)
   
        self.add(vbox)
        self.set_position(gtk.WIN_POS_CENTER)
        self.show_all()

PyApp()
gtk.main()
</pre>

<p>
In the code example, we have a label. We change the it's text
attributes with the markup language.
</p>

<pre class="explanation">
 quote = "&lt;span foreground='blue' size='19000'&gt;The only victory over love is flight&lt;/span&gt;"
</pre>

<p>
This is the text with the markup language. 
</p>

<pre class="explanation">
 label = gtk.Label()
 label.set_markup(quote)
</pre>

<p>
We create a label widget and set a markup text for it.
</p>

<br>
<img src="/img/gui/pygtk/markup.png" alt="Using markup">
<div class="figure">Figure: Using markup</div>
<br>


<h2>Pango layout</h2>

<p>
Pango layout is an object representing a paragraph of text with attributes. 
</p>

<div class="codehead">layout.py</div>
<pre class="code"> 
#!/usr/bin/python

# ZetCode PyGTK tutorial 
#
# This example shows pango Layout
# in action
#
# author: jan bodnar
# website: zetcode.com 
# last edited: February 2009


import gtk
import pango


lyrics = """Meet you downstairs in the bar and heard
your rolled up sleeves and your skull t-shirt
You say why did you do it with him today?
and sniff me out like I was Tanqueray

cause you're my fella, my guy
hand me your stella and fly
by the time I'm out the door
you tear men down like Roger Moore

I cheated myself
like I knew I would
I told ya, I was trouble
you know that I'm no good"""

class Area(gtk.DrawingArea):
    def __init__(self):
        super(Area, self).__init__()
        self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(16400, 16400, 16440))
        self.connect("expose_event", self.expose)

    def expose(self, widget, event):
        
        gc = self.get_style().fg_gc[gtk.STATE_NORMAL]
        font_desc = pango.FontDescription('Sans 10')
        
        layout = self.create_pango_layout(lyrics)
        width, height = self.get_size_request()
        
        attr = pango.AttrList()
        
        fg_color = pango.AttrForeground(60535, 60535, 60535, 0, -1)
        attr.insert(fg_color)
        
        layout.set_width(pango.SCALE * self.allocation.width)
        layout.set_spacing(pango.SCALE * 3)
        layout.set_alignment(pango.ALIGN_CENTER)
        layout.set_font_description(font_desc)
        layout.set_attributes(attr)
        
        self.window.draw_layout(gc, 0, 5, layout)
        
        

class PyApp(gtk.Window): 
    def __init__(self):
        super(PyApp, self).__init__()
        
        self.connect("destroy", gtk.main_quit)
        self.set_title("You know I'm no Good")
        
        self.add(Area())
        self.set_size_request(300, 300)
        self.set_position(gtk.WIN_POS_CENTER)
        self.show_all()


PyApp()
gtk.main()
</pre>

<p>
In the previous examples, we were modifying text in existing 
widgets. Now we are going to draw the text using the pango 
layout on the <b class="keyword">DrawingArea</b> widget. 
We will be drawing using the <b>Gdk</b> drawing tools.
</p>

<pre class="explanation">
 gc = self.get_style().fg_gc[gtk.STATE_NORMAL]
</pre>

<p>
We get the graphics contex of the drawing area widget. 
</p>

<pre class="explanation">
 layout = self.create_pango_layout(lyrics)
</pre>

<p>
Here create the pango layout object. 
</p>

<pre class="explanation">
 layout.set_width(pango.SCALE * self.allocation.width)
 layout.set_spacing(pango.SCALE * 3)
 layout.set_alignment(pango.ALIGN_CENTER)
 layout.set_font_description(font_desc)
 layout.set_attributes(attr)
</pre>

<p>
We modify layout's width, spacing, alignment, font and set text attributes. 
</p>

<pre class="explanation">
 self.window.draw_layout(gc, 0, 5, layout)
</pre>

<p>
The layout is being drawn on the window.
</p>


<br>
<img src="/img/gui/pygtk/layout.png" alt="Layout">
<div class="figure">Figure: Layout</div>


<hr class="btm">

<p>
In this chapter of the PyGTK programming library, we further worked with
pango library.
</p>


<br>
<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div> 
<br>


<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡ 
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified February 10, 2009  <span class="copyright">&copy; 2007 - 2012 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>

